package flca.voicenav.util;

import java.io.BufferedReader;
import java.io.IOException;
import java.io.InputStreamReader;
import java.io.StringReader;
import java.net.URL;

import org.xmlpull.v1.XmlPullParser;
import org.xmlpull.v1.XmlPullParserException;
import org.xmlpull.v1.XmlPullParserFactory;

import android.util.Log;
import flca.voicenav.VoiceNavUtilsConstants;
import flca.voicenav.model.GpxRoute;
import flca.voicenav.model.TrkPt;

public class GpxXmlParser implements VoiceNavUtilsConstants
{
	private TrkPt trkPt = null;
	
	public GpxRoute getRoute(URL aUrl)
	{
		try {
			String xml = readFile(aUrl);
			GpxRoute r = parse(xml);
			r.setName(aUrl.getFile());
			return r;
		} catch (Exception ex) {
			Log.e(TAG, "parsing route " + ex);
			return null;
		}
	}

	private String readFile(URL aUrl) throws Exception
	{
		StringBuffer result = new StringBuffer();

		BufferedReader in = new BufferedReader(new InputStreamReader(aUrl.openStream()));

		String inputLine;
		while ((inputLine = in.readLine()) != null) {
			result.append(inputLine + "\n");
		}
		in.close();

		return result.toString();
	}

	private GpxRoute parse(String aXml) throws Exception
	{
		GpxRoute result = new GpxRoute();

		XmlPullParserFactory factory = XmlPullParserFactory.newInstance();
		factory.setNamespaceAware(true);
		XmlPullParser xpp = factory.newPullParser();

		pullParseXml(aXml, result, xpp);

		
		return result;
	}

	private void pullParseXml(String aXml, GpxRoute result, XmlPullParser xpp)
			throws XmlPullParserException, IOException {
		xpp.setInput(new StringReader(aXml));
		int eventType = xpp.getEventType();
		while (eventType != XmlPullParser.END_DOCUMENT) {
			if (eventType == XmlPullParser.START_DOCUMENT) {
			} else if (eventType == XmlPullParser.START_TAG) {
				if ("trkpt".equals(xpp.getName())) {
					trkPt = new TrkPt();
					processStartTrkPt(xpp);
				}
			} else if (eventType == XmlPullParser.END_TAG) {
				if ("trkpt".equals(xpp.getName())) {
					processEndTrkPt(xpp, result);
				}
			} 
			eventType = xpp.next();
		}
	}

	private void processStartTrkPt(XmlPullParser xpp)
	{
		for (int i = 0; i < xpp.getAttributeCount(); i++) {
			String attrname = xpp.getAttributeName(i);
			if ("lat".equalsIgnoreCase(attrname)) {
				trkPt.setLat(Double.parseDouble(xpp.getAttributeValue(i)));
			} else if ("lon".equalsIgnoreCase(attrname) || "lng".equalsIgnoreCase(attrname)) {
				trkPt.setLng(Double.parseDouble(xpp.getAttributeValue(i)));
			} else if ("elev".equalsIgnoreCase(attrname)) {
				trkPt.setElevation(Double.parseDouble(xpp.getAttributeValue(i)));
			} else if ("cmt".equalsIgnoreCase(attrname)) {
				trkPt.setComment(xpp.getAttributeValue(i));
			}
		}
	}
	
	private void processEndTrkPt(XmlPullParser xpp, GpxRoute result)
	{
		if (trkPt.isValid()) {
			result.getCoordinates().add(trkPt);
		} else {
			Log.e(TAG, "trkpr not valid??");
		}
	}
	
}